import {
  useMessage as useWotdMessage,
  useNotify as useWotdNotify,
  useToast as useWotdToast,
} from 'wot-design-uni';
import type { InputValidate, MessageType } from 'wot-design-uni/components/wd-message-box/types';
import type { ToastLoadingType } from 'wot-design-uni/components/wd-toast/types';

import { rmUndefinedProps } from '@/utils';
import { isFunction } from '@/utils/is';

let wotdToast: ReturnType<typeof useWotdToast>;
let wotdNotify: ReturnType<typeof useWotdNotify>;
let wotdMessage: ReturnType<typeof useWotdMessage>;

/** setup Message instance with glob */
export function setupMessage(
  toast: ReturnType<typeof useWotdToast>,
  notify: ReturnType<typeof useWotdNotify>,
  message: ReturnType<typeof useWotdMessage>,
) {
  wotdToast = toast;
  wotdNotify = notify;
  wotdMessage = message;
}

/** 消息参数 */
export interface MessageOptions {
  /** 消息内容 */
  content?: string;

  /** 弹窗层级 */
  zIndex?: number;
}
/** 轻提示参数 */
export interface ToastOptions extends MessageOptions {
  /**
   * 显示位置
   * - top: 居上显示
   * - middle: 居中显示
   * - bottom: 居底显示
   */
  position?: 'top' | 'middle' | 'bottom';
  /** 提示的延迟时间，单位毫秒。 */
  duration?: number;
  /** 图标 */
  icon?: 'success' | 'error' | 'warning' | 'loading' | 'info';
  /** 图标尺寸 */
  iconSize?: number;
  /** 图标类名 */
  iconClass?: string;
  /** 图标颜色 */
  iconColor?: string;
  /** 加载中图标类型 */
  loadingType?: ToastLoadingType;
  /** 加载中图标尺寸 */
  loadingSize?: number;
  /** 加载中图标颜色 */
  loadingColor?: string;

  /** 类名前缀，用于使用自定义图标 */
  classPrefix?: string;

  /** 是否显示透明蒙层，防止穿透。 */
  mask?: boolean;

  /** 完全展示后的回调函数 */
  opened?: (result: any) => void;
  /** 完全关闭时的回调函数 */
  closed?: (result: any) => void;
}
/** 通知参数 */
export interface NotifyOptions extends MessageOptions {
  /**
   * 显示位置
   * - top: 居上显示
   * - bottom: 居底显示
   */
  position?: 'top' | 'bottom';
  /** 提示的延迟时间，单位毫秒。 */
  duration?: number;
  /** 类型 */
  type?: 'primary' | 'success' | 'danger' | 'warning';
  /** 字体颜色 */
  color?: string;
  /** 顶部安全高度 */
  safeHeight?: number;
  /** 背景颜色 */
  background?: string;
}
/** 弹窗参数 */
export interface ModalOptions extends MessageOptions {
  /** 弹框类型 */
  type?: MessageType;
  /** 标题 */
  title?: string;
  /** 确定按钮的文字 */
  confirmText?: string;
  /** 确定按钮的文字颜色 */
  confirmColor?: string;
  /** 是否显示取消按钮 */
  showCancel?: boolean;
  /** 取消按钮的文字 */
  cancelText?: string;
  /** 取消按钮的文字颜色 */
  cancelColor?: string;

  /** 是否支持点击蒙层进行关闭 */
  closeOnClickModal?: boolean;

  /** 当type为prompt时，输入框类型 */
  inputType?: 'text' | 'number' | 'digit' | 'idcard';
  /** 当type为prompt时，输入框初始值 */
  inputValue?: string | number;
  /** 当type为prompt时，输入框placeholder */
  inputPlaceholder?: string;
  /** 当type为prompt时，输入框正则校验，点击确定按钮时进行校验 */
  inputPattern?: RegExp;
  /** 当type为prompt时，输入框校验函数，点击确定按钮时进行校验 */
  inputValidate?: InputValidate | null;
  /** 当type为prompt时，输入框检验不通过时的错误提示文案 */
  inputError?: string;
  /** 是否展示错误信息 */
  showErr?: boolean;

  /** 弹层内容懒渲染，触发展示时才渲染内容 */
  lazyRender?: boolean;
}
/** 弹窗返回结果 */
export interface ModalResult {
  /** 为 true 时，表示用户点击了确定按钮 */
  confirm: boolean;
  /** 为 true 时，表示用户点击了取消 */
  cancel: boolean;
  /** 当type为prompt时，用户输入的值 */
  value?: string | number;
}

/** 轻提示接口 */
export interface ToastApi {
  /** 打开Toast */
  show(config: ToastOptions): void;
  /** 成功提示 */
  success(config: ToastOptions): void;
  /** 错误提示 */
  error(config: ToastOptions): void;
  /** 常规提示 */
  info(config: ToastOptions): void;
  /** 警告提示 */
  warning(config: ToastOptions): void;
  /** 加载提示 */
  loading(config: ToastOptions): void;
  /** 隐藏 loading 提示 */
  hideLoading(): void;
  /** 隐藏消息提示 */
  close(): void;
}
/** 通知接口 */
export interface NotifyApi {
  /** 打开Notify */
  show(config: NotifyOptions): void;
  /** 信息通知 */
  info(config: NotifyOptions): void;
  /** 成功通知 */
  success(config: NotifyOptions): void;
  /** 错误通知 */
  error(config: NotifyOptions): void;
  /** 警告通知 */
  warning(config: NotifyOptions): void;
  /** 关闭Notify */
  close(): void;
}
/** 弹窗接口 */
export interface ModalApi {
  /** 打开Modal */
  show(config: ModalOptions): Promise<ModalResult>;
  /** 打开Alert弹框 */
  alert(config: ModalOptions): Promise<ModalResult>;
  /** 打开Confirm弹框 */
  confirm(config: ModalOptions): Promise<ModalResult>;
  /** 打开Prompt弹框 */
  prompt(config: ModalOptions): Promise<ModalResult>;
  /** 关闭Modal */
  close(): void;
}

/** 初始化 Wotd Toast 参数 */
function initWotdToastProps(config: ToastOptions) {
  return rmUndefinedProps({
    msg: config.content,
    position: config.position || 'middle',
    zIndex: config.zIndex || 999999999,
    duration: config.duration,
    iconName: config.icon,
    iconSize: config.iconSize,
    iconClass: config.iconClass,
    iconColor: config.iconColor,
    loadingType: config.loadingType,
    loadingSize: config.loadingSize,
    loadingColor: config.loadingColor,
    classPrefix: config.classPrefix,
    cover: config.mask,
    opened: isFunction(config.opened) ? () => config.opened(wotdToast) : undefined,
    closed: isFunction(config.closed) ? () => config.closed(wotdToast) : undefined,
  });
}
/** 初始化 Uni Toast 参数 */
function initUniToastProps(config: ToastOptions) {
  const position: 'top' | 'center' | 'bottom' =
    config.position === 'middle' ? 'center' : config.position || 'center';
  let icon: 'success' | 'loading' | 'error' | 'none' | 'fail' | 'exception' = 'none';
  if (config.icon === 'warning') {
    icon = 'error';
  } else {
    icon = config.icon as 'success' | 'loading' | 'error' | 'none' | 'fail' | 'exception';
  }

  return rmUndefinedProps({
    title: config.content,
    position,
    duration: config.duration,
    icon,
    mask: config.mask,
    complete: isFunction(config.opened) ? config.opened : undefined,
  });
}

/** 初始化 Wotd Modal 参数 */
function initWotdModalProps(config: ModalOptions) {
  return rmUndefinedProps({
    type: config.type,
    title: config.title,
    msg: config.content,
    zIndex: config.zIndex || 999999999,
    confirmButtonText: config.confirmText,
    showCancelButton: config.showCancel,
    cancelButtonText: config.cancelText,
    closeOnClickModal: config.closeOnClickModal || false,
    inputType: config.inputType,
    inputValue: config.inputValue,
    inputPlaceholder: config.inputPlaceholder,
    inputPattern: config.inputPattern,
    inputValidate: config.inputValidate,
    inputError: config.inputError,
    showErr: config.showErr,
    lazyRender: config.lazyRender,
  });
}
/** 初始化 Uni Modal 参数 */
function initUniModalProps(config: ModalOptions) {
  return rmUndefinedProps({
    title: config.title,
    content: config.content,
    confirmText: config.confirmText,
    confirmColor: config.confirmColor,
    showCancel: config.showCancel,
    cancelText: config.cancelText,
    cancelColor: config.cancelColor,
    editable: config.type === 'prompt',
    placeholderText: config.inputPlaceholder,
  });
}

/** 初始化 Wotd Notify 参数 */
function initWotdNotifyProps(config: NotifyOptions) {
  return rmUndefinedProps({
    message: config.content,
    position: config.position || 'top',
    zIndex: config.zIndex || 999999999,
    duration: config.duration,
    type: config.type,
    color: config.color,
    safeHeight: config.safeHeight,
    background: config.background,
  });
}
/** 初始化 Uni Notify 参数 */
function initUniNotifyProps(config: NotifyOptions) {
  const position: 'top' | 'bottom' = config.position || 'top';
  return rmUndefinedProps({
    title: config.content,
    position,
    duration: config.duration,
  });
}

/** 创建轻提示 */
function createToast(): ToastApi {
  return {
    show(config: ToastOptions) {
      if (wotdToast) {
        wotdToast.show(initWotdToastProps(config));
      } else {
        uni.showToast(initUniToastProps(config));
      }
    },
    success(config: ToastOptions) {
      if (wotdToast) {
        wotdToast.success(initWotdToastProps(config));
      } else {
        uni.showToast({ icon: 'success', ...initUniToastProps(config) });
      }
    },
    error(config: ToastOptions) {
      if (wotdToast) {
        wotdToast.error(initWotdToastProps(config));
      } else {
        uni.showToast({ icon: 'error', ...initUniToastProps(config) });
      }
    },
    info(config: ToastOptions) {
      if (wotdToast) {
        wotdToast.info(initWotdToastProps(config));
      } else {
        uni.showToast({ icon: 'none', ...initUniToastProps(config) });
      }
    },
    warning(config: ToastOptions) {
      if (wotdToast) {
        wotdToast.warning(initWotdToastProps(config));
      } else {
        uni.showToast({ icon: 'error', ...initUniToastProps(config) });
      }
    },
    loading(config: ToastOptions) {
      if (wotdToast) {
        wotdToast.loading(initWotdToastProps(config));
      } else {
        uni.showToast({ icon: 'loading', ...initUniToastProps(config) });
      }
    },
    hideLoading() {
      if (wotdToast) {
        wotdToast.close();
      } else {
        uni.hideLoading();
      }
    },
    close() {
      if (wotdToast) {
        wotdToast.close();
      } else {
        uni.hideToast();
      }
    },
  };
}
/** 创建通知 */
function createNotify(): NotifyApi {
  return {
    show(config: NotifyOptions) {
      if (wotdNotify) {
        wotdNotify.showNotify(initWotdNotifyProps(config));
      } else {
        uni.showToast(initUniNotifyProps(config));
      }
    },
    info(config: NotifyOptions) {
      if (wotdNotify) {
        wotdNotify.showNotify({ type: 'primary', ...initWotdNotifyProps(config) });
      } else {
        uni.showToast({ icon: 'none', ...initUniNotifyProps(config) });
      }
    },
    success(config: NotifyOptions) {
      if (wotdNotify) {
        wotdNotify.showNotify({ type: 'success', ...initWotdNotifyProps(config) });
      } else {
        uni.showToast({ icon: 'success', ...initUniNotifyProps(config) });
      }
    },
    error(config: NotifyOptions) {
      if (wotdNotify) {
        wotdNotify.showNotify({ type: 'danger', ...initWotdNotifyProps(config) });
      } else {
        uni.showToast({ icon: 'error', ...initUniNotifyProps(config) });
      }
    },
    warning(config: NotifyOptions) {
      if (wotdNotify) {
        wotdNotify.showNotify({ type: 'warning', ...initWotdNotifyProps(config) });
      } else {
        uni.showToast({ icon: 'error', ...initUniNotifyProps(config) });
      }
    },
    close() {
      if (wotdNotify) {
        wotdNotify.closeNotify();
      } else {
        uni.showToast();
      }
    },
  };
}
/** 创建弹窗 */
function createModal(): ModalApi {
  return {
    async show(config: ModalOptions) {
      let result: ModalResult = { confirm: false, cancel: false };
      if (wotdMessage) {
        const res = await wotdMessage.show(initWotdModalProps(config));
        result = {
          confirm: res.action === 'confirm',
          cancel: res.action === 'cancel',
          value: res.value,
        };
      } else {
        const res = await uni.showModal(initUniModalProps(config));
        result = {
          confirm: res.confirm,
          cancel: res.cancel,
          value: res.content,
        };
      }
      return result;
    },
    async alert(config: ModalOptions) {
      let result: ModalResult = { confirm: false, cancel: false };
      if (wotdMessage) {
        const res = await wotdMessage.alert(initWotdModalProps(config));
        result = {
          confirm: res.action === 'confirm',
          cancel: res.action === 'cancel',
          value: res.value,
        };
      } else {
        const res = await uni.showModal({ showCancel: false, ...initUniModalProps(config) });
        result = {
          confirm: res.confirm,
          cancel: res.cancel,
          value: res.content,
        };
      }
      return result;
    },
    async confirm(config: ModalOptions) {
      let result: ModalResult = { confirm: false, cancel: false };
      if (wotdMessage) {
        const res = await wotdMessage.confirm(initWotdModalProps(config));
        result = {
          confirm: res.action === 'confirm',
          cancel: res.action === 'cancel',
          value: res.value,
        };
      } else {
        const res = await uni.showModal({ showCancel: true, ...initUniModalProps(config) });
        result = {
          confirm: res.confirm,
          cancel: res.cancel,
          value: res.content,
        };
      }
      return result;
    },
    async prompt(config: ModalOptions) {
      let result: ModalResult = { confirm: false, cancel: false };
      if (wotdMessage) {
        const res = await wotdMessage.prompt(initWotdModalProps(config));
        result = {
          confirm: res.action === 'confirm',
          cancel: res.action === 'cancel',
          value: res.value,
        };
      } else {
        const res = await uni.showModal({ editable: true, ...initUniModalProps(config) });
        result = {
          confirm: res.confirm,
          cancel: res.cancel,
          value: res.content,
        };
      }
      return result;
    },
    close() {
      if (wotdMessage) {
        wotdMessage.close();
      }
    },
  };
}

/** 使用消息函数 */
export function useMessage() {
  return {
    /** 轻提示 */
    toast: createToast(),
    /** 通知 */
    notify: createNotify(),
    /** 弹窗 */
    modal: createModal(),
  };
}
